'''
Copyright 2010 Indra Bagus <indra.bagus@gmail.com> 
    
Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 

    http://www.apache.org/licenses/LICENSE-2.0 
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. 
'''


#!/usr/bin/env python

import sys

from OfdmaDistiller.WimaxStreamHandler import ULMAPHandler, UCDHandler,\
    MMHandlerCollection, DLMAPHandler, DCDHandler, DataHandler

from OfdmaDistiller.Decoder import PDUDecoder, PDUMMError
from OfdmaDistiller.ArgvConfiguration import ArgvParser, DistillerConfig
from OfdmaDistiller.TextOutput import TextOutput
from OfdmaDistiller.Dictionary import UCDDict
from OfdmaDistiller.Input import CArrayFormat
from OfdmaDistiller.Tools import DumpBuffString



class UCDDistillerHandler(UCDHandler):
    def __init__(self,output):
        super(UCDDistillerHandler,self).__init__()
        assert(isinstance(output,TextOutput))
        self._output = output

        
    def OnStartPDU(self,payload,macheader):
        super(UCDDistillerHandler,self).OnStartPDU(payload,macheader)
        self._output.BeginOutput()
        self._output.PrintPDUPayload(payload)
        self._output.AddLine()
        self._output.PrintPDUName('Uplink Channel Descriptor')
        self._output.AddLine()     
        self._output.PrintMACHeaderGeneric(macheader)   
        self._output.AddLine()
        
        
    def OnReceiveCRC(self,calc_crc,current_crc):
        self._output.PrintCRC(calc_crc,current_crc)


    def OnReceiveUCD(self,ucd_header):
        super(UCDDistillerHandler,self).OnReceiveUCD(ucd_header)
        self._output.GetSection().SetSectionName('UCD')
        self._output.GetSection().SetInfoTable('Configuration Change Count',
                                               int(ucd_header.configuration_change_count))
        self._output.GetSection().SetInfoTable('Ranging Backoff Start',
                                               int(ucd_header.ranging_back_off_start),
                                               str(ucd_header.ranging_back_off_start))
        self._output.GetSection().SetInfoTable('Ranging Backoff End',
                                               int(ucd_header.ranging_back_off_end),
                                               str(ucd_header.ranging_back_off_end))
        self._output.GetSection().SetInfoTable('Request Backoff Start',
                                               int(ucd_header.request_back_off_start),
                                               str(ucd_header.request_back_off_start))
        self._output.GetSection().SetInfoTable('Request Backoff End',
                                               int(ucd_header.request_back_off_end),
                                               str(ucd_header.request_back_off_end))
        self._output.AddLine()
        self._output.GetSection().SetSectionName('TLV')
    
    
    def OnReceiveULBurstProfile(self,ulburstprofile):
        self._output.GetSection().SetInfoTable('Type',1, 'Burst Profile')
        self._output.GetSection().SetInfoTable('Length',ulburstprofile.length)
        self._output.GetSection().SetInfoTable('Reserved',0)
        self._output.GetSection().SetInfoTable('UIUC',ulburstprofile.uiuc)
        self._output.AddLine()        
        subsection = self._output.GetSection().GetSection()
        subsection.SetSectionName('Uplink Burst Profile')
        for tlv in ulburstprofile.tlv_list:
            try:
                strinfo = UCDDict.ULBurstProfileDict.tlv_type[tlv.Type]
            except KeyError: strinfo = ''            
            subsection.SetInfoTable('Type',tlv.Type,strinfo)
            subsection.SetInfoTable('Length',tlv.Length)
            subsection.SetInfoTable('Value',int(tlv.Value))
            self._output.AddLine()
            
        self._output.AddLine()
    
    
    def OnReceiveULChannelEncoding(self,tlv):
        self._output.GetSection().SetInfoTable('Type',int(tlv.Type), str(tlv.Type))
        self._output.GetSection().SetInfoTable('Length',int(tlv.Length))
        if(tlv.Length > 4):
            self._output.GetSection().SetInfoTable('Value',None,DumpBuffString(tlv.Value.GetValueAsString(),tlv.Length))
        else:
            self._output.GetSection().SetInfoTable('Value',int(tlv.Value))
        self._output.AddLine()



class ULMAPDistillerHandler(ULMAPHandler):
    def __init__(self,output):
        super(ULMAPDistillerHandler,self).__init__()
        assert(isinstance(output,TextOutput))
        self._output = output

        
    def __output_cid_uiuc__(self,ulmapie):
        self._output.GetSection().SetInfoTable('CID', int(ulmapie.cid))
        self._output.GetSection().SetInfoTable('UIUC', int(ulmapie.uiuc))

        
    def __output_extuiuc_length__(self,ulmap_ext_ie):
        self._output.GetSection().SetInfoTable('Extended UIUC',int(ulmap_ext_ie.ext_uiuc))
        self._output.GetSection().SetInfoTable('Length',int(ulmap_ext_ie.length))        

        
    def OnStartPDU(self,payload,macheader):
        super(ULMAPDistillerHandler,self).OnStartPDU(payload,macheader)
        self._output.BeginOutput()
        self._output.PrintPDUPayload(payload)
        self._output.AddLine()
        self._output.PrintPDUName('ULMAP')
        self._output.AddLine()
        self._output.PrintMACHeaderGeneric(macheader)
        self._output.AddLine()
        self._output.GetSection().SetSectionName('ULMAP')


    def OnReceiveCRC(self,calc_crc,current_crc):
        self._output.PrintCRC(calc_crc,current_crc)
        
                            
    def OnReceiveULMAP(self,ulmap):
        super(ULMAPDistillerHandler,self).OnReceiveULMAP(ulmap)
        
        #print fdd partition flag
        self._output.GetSection().SetInfoTable('FDD Partition Flag',
                                               int(ulmap.fdd_part_flag),
                                               str(ulmap.fdd_part_flag))
        self._output.GetSection().SetInfoTable('Reserved', 0)
        self._output.GetSection().SetInfoTable('UCD Count', int(ulmap.ucd_count))
        self._output.GetSection().SetInfoTable('Allocation Start Time', int(ulmap.alloc_start_time))
        self._output.GetSection().SetInfoTable('No. OFDMA Symbols', int(ulmap.no_ofdma_symbols))
        self._output.AddLine()
    
    def OnReceiveULMAPIeFastFeedBack(self,ulmapie):
        self._output.GetSection().SetSectionName('Fast Feedback Allocation')
        self.__output_cid_uiuc__(ulmapie)
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset',int(ulmapie.symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel Offset',int(ulmapie.subchannel_offset))
        self._output.GetSection().SetInfoTable('No OFDMA Symbols',int(ulmapie.no_ofdma_symbols))                
        self._output.GetSection().SetInfoTable('No Subchannels',int(ulmapie.no_subchannels))                        
        self._output.GetSection().SetInfoTable('Reserved',int(ulmapie.reserved))
        self._output.AddLine()
        
    def OnReceiveULMAPIeBurstProfile(self,ulmapie):
        self._output.GetSection().SetSectionName('ULMAP IE Burst Profile')
        self.__output_cid_uiuc__(ulmapie)
        
        self._output.GetSection().SetInfoTable('Duration', int(ulmapie.duration))
        self._output.GetSection().SetInfoTable('Repetition Coding Ind', 
                                               int(ulmapie.repet_coding_ind),
                                               str(ulmapie.repet_coding_ind))
        if(ulmapie.aas_amc_zone_mode == True):
            self._output.GetSection().SetInfoTable('Slot Offset',int(ulmapie.slot_offset))
            
        self._output.AddLine()    
    
    
    def OnReceiveULMAPIeRangingOpportunity(self,ulmapie):
        self._output.GetSection().SetSectionName('ULMAP IE CDMA Bandwidth Request/Ranging Opp')
        self.__output_cid_uiuc__(ulmapie)
        self._output.GetSection().SetInfoTable('OFDMA Symbol offset', int(ulmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel offset', int(ulmapie.subchannel_offset))
        self._output.GetSection().SetInfoTable('No OFDMA Symbols', int(ulmapie.no_ofdma_symbols))
        self._output.GetSection().SetInfoTable('No Subchannels', int(ulmapie.no_subchannels))

        
        self._output.GetSection().SetInfoTable('Ranging Method',
                                               int(ulmapie.ranging_method),
                                               str(ulmapie.ranging_method))
        
        self._output.GetSection().SetInfoTable('Dedicated Ranging Ind', 
                                               int(ulmapie.dedicated_ranging_indicator), 
                                               str(ulmapie.dedicated_ranging_indicator))
        self._output.AddLine()        
    
    
    def OnReceiveULMAPIeCDMAAllocation(self,ulmapie):
        self._output.GetSection().SetSectionName('ULMAP IE CDMA Allocation')
        self.__output_cid_uiuc__(ulmapie)
        self._output.GetSection().SetInfoTable('Duration', 
                                               int(ulmapie.duration),
                                               str(ulmapie.duration))
        self._output.GetSection().SetInfoTable('UIUC Transmission', 
                                               int(ulmapie.uiuc_transmission),
                                               str(ulmapie.uiuc_transmission))
        self._output.GetSection().SetInfoTable('Repetition Coding Ind',
                                               int(ulmapie.repet_coding_ind),
                                               str(ulmapie.repet_coding_ind))
        self._output.GetSection().SetInfoTable('Frame Number Index', 
                                               int(ulmapie.frame_number_index),
                                               str(ulmapie.frame_number_index))
        self._output.GetSection().SetInfoTable('Ranging Code', 
                                               int(ulmapie.ranging_code),
                                               str(ulmapie.ranging_code))
        self._output.GetSection().SetInfoTable('Ranging Symbol', 
                                               int(ulmapie.ranging_symbol),
                                               str(ulmapie.ranging_symbol))
        self._output.GetSection().SetInfoTable('Ranging Subchannel',
                                               int(ulmapie.ranging_subchannel),
                                               str(ulmapie.ranging_subchannel))
        self._output.GetSection().SetInfoTable('Bandwidth Request Mandatory',
                                               int(ulmapie.bw_req_mandatory),
                                               str(ulmapie.bw_req_mandatory))
        self._output.AddLine()


    def OnReceivePowerControl(self,ulmapie): 
        super(ULMAPDistillerHandler,self).OnReceivePowerControl(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE Power Control')
        self.__output_cid_uiuc__(ulmapie)
        self.__output_extuiuc_length__(ulmapie)
        self._output.GetSection().SetInfoTable('Power Control',
                                               int(ulmapie.power_control),
                                               str(ulmapie.power_control))
        self._output.GetSection().SetInfoTable('Power Measurement Frame',
                                               int(ulmapie.power_measurement_frame),
                                               str(ulmapie.power_measurement_frame))
        self._output.AddLine()
    
    
    def OnReceiveAAS_UL(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveAAS_UL(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE AAS UL')
        self.__output_cid_uiuc__(ulmapie)
        self.__output_extuiuc_length__(ulmapie)
        self._output.GetSection().SetInfoTable('Permutation',
                                               int(ulmapie.permutation),
                                               str(ulmapie.permutation))
        self._output.GetSection().SetInfoTable('UL Perm Base',
                                               int(ulmapie.ul_perm_base),
                                               str(ulmapie.ul_perm_base))
        self._output.GetSection().SetInfoTable('Symbol Offset',
                                               int(ulmapie.symbol_offset),
                                               str(ulmapie.symbol_offset))        
        self._output.GetSection().SetInfoTable('AAS Zone Length',
                                               int(ulmapie.aas_zone_length),
                                               str(ulmapie.aas_zone_length)) 
        self._output.GetSection().SetInfoTable('UL Preamble Config',
                                               int(ulmapie.ul_preamble_config),
                                               str(ulmapie.ul_preamble_config))
        self._output.GetSection().SetInfoTable('Reserved',
                                               int(ulmapie.reserved),
                                               str(ulmapie.reserved))
        self._output.AddLine()
    
    
    def OnReceiveCQICHAlloc(self,ulmapie) : 
        pass
    
    
    def OnReceiveULZone(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveULZone(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE UL Zone')
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset',
                                               int(ulmapie.ofdma_symbol_offset),
                                               str(ulmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Permutation',
                                               int(ulmapie.permutation),
                                               str(ulmapie.permutation))
        self._output.GetSection().SetInfoTable('UL_PermBase',
                                               int(ulmapie.ul_permbase),
                                               str(ulmapie.ul_permbase))
        self._output.GetSection().SetInfoTable('AMC type',
                                               int(ulmapie.amc_type),
                                               str(ulmapie.amc_type))
        self._output.GetSection().SetInfoTable('Use All Subchannel Indicator',
                                               int(ulmapie.use_all_subch),
                                               str(ulmapie.use_all_subch))
        self._output.GetSection().SetInfoTable('Disable subchannel rotation',
                                               int(ulmapie.disable_subch_rotation),
                                               str(ulmapie.disable_subch_rotation))
        self._output.GetSection().SetInfoTable('H-FDD over subframe allocation',
                                               int(ulmapie.hfdd_over_subframe_alloc),
                                               str(ulmapie.hfdd_over_subframe_alloc))
        self._output.GetSection().SetInfoTable('H-FDD Inter-UL_gap allocation',
                                               int(ulmapie.hfdd_inter_ul_gap_alloc),
                                               str(ulmapie.hfdd_inter_ul_gap_alloc))    
        self._output.GetSection().SetInfoTable('Reserved',
                                               int(ulmapie.reserved),
                                               str(ulmapie.reserved))     
        self._output.AddLine()       
    
    
    def OnReceivePhysicalModifier(self,ulmapie) :
        super(ULMAPDistillerHandler,self).OnReceivePhysicalModifier(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE Physical Modifier')
        self._output.GetSection().SetInfoTable('Preamble Modifier Type',
                                               int(ulmapie.preamble_modifier_type),
                                               str(ulmapie.preamble_modifier_type))
        if(int(ulmapie.preamble_modifier_type) == 0):
            self._output.GetSection().SetInfoTable('Preamble frequency shift index',
                                               int(ulmapie.preamble_frequency_shift_index),
                                               str(ulmapie.preamble_frequency_shift_index))
        else:
            self._output.GetSection().SetInfoTable('Preamble time shift index',
                                               int(ulmapie.preamble_time_shift_index),
                                               str(ulmapie.preamble_time_shift_index))
        self._output.GetSection().SetInfoTable('Pilot Pattern Modifier',
                                               int(ulmapie.pilot_pattern_modifier),
                                               str(ulmapie.pilot_pattern_modifier))
        self._output.GetSection().SetInfoTable('Pilot Pattern Index',
                                               int(ulmapie.pilot_pattern_index),
                                               str(ulmapie.pilot_pattern_index))
        self._output.AddLine()

    
    def OnReceiveFastTracking(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveFastTracking(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE Fast Tracking')
        self._output.GetSection().SetInfoTable('Length',
                                               int(ulmapie.length))
        self._output.GetSection().SetInfoTable('MAP Index',
                                               int(ulmapie.map_index),
                                               str(ulmapie.map_index))
        self._output.GetSection().SetInfoTable('Reserved',
                                               int(ulmapie.reserved))
        self._output.AddLine()
        ie_iter = ulmapie.GetFastTrackingIterator()
        while True:
            try:
                fasttracking = ie_iter.next()
                self._output.GetSection().SetInfoTable('Power correction',
                                                       int(fasttracking[0]),
                                                       str(fasttracking[0]))
                self._output.GetSection().SetInfoTable('Frequency correction',
                                                       int(fasttracking[1]),
                                                       str(fasttracking[1]))
                self._output.GetSection().SetInfoTable('Time correction',
                                                       int(fasttracking[2]),
                                                       str(fasttracking[2]))
            except StopIteration:
                break
        self._output.AddLine()
    
    
    def OnReceiveULPUSCBurstAlloc(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveULPUSCBurstAlloc(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE PUSC Burst Allocation')
        self._output.GetSection().SetInfoTable('UIUC',
                                               int(ulmapie.uiuc),
                                               str(ulmapie.uiuc))
        self._output.GetSection().SetInfoTable('Segment',
                                               int(ulmapie.segment),
                                               str(ulmapie.segment))
        self._output.GetSection().SetInfoTable('UL_Permbase',
                                               int(ulmapie.ul_permbase),
                                               str(ulmapie.ul_permbase))
        self._output.GetSection().SetInfoTable('OFDMA symbol offset',
                                               int(ulmapie.ofdma_symbol_offset),
                                               str(ulmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel offset',
                                               int(ulmapie.subchannel_offset),
                                               str(ulmapie.subchannel_offset)) 
        self._output.GetSection().SetInfoTable('Duration',
                                               int(ulmapie.duration),
                                               str(ulmapie.duration))
        self._output.GetSection().SetInfoTable('Repetition coding indicator',
                                               int(ulmapie.repet_coding_ind),
                                               str(ulmapie.repet_coding_ind))
        self._output.GetSection().SetInfoTable('Reserved',
                                               int(ulmapie.reserved),
                                               str(ulmapie.reserved))
        self._output.AddLine()
    
    
    def OnReceiveFastRanging(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveFastRanging(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE Fast Ranging')
        self._output.GetSection().SetInfoTable('HO ID Indicator',
                                               int(ulmapie.ho_id_ind),
                                               str(ulmapie.ho_id_ind))
        if(int(ulmapie.ho_id_ind) == 1):
            self._output.GetSection().SetInfoTable('HO ID',
                                                   int(ulmapie.ho_id),
                                                   str(ulmapie.ho_id))
        else:
            self._output.GetSection().SetInfoTable('MAC Address',None,
                                                   str(ulmapie.mac_address))
        self._output.GetSection().SetInfoTable('UIUC',
                                               int(ulmapie.uiuc),
                                               str(ulmapie.uiuc))
        self._output.GetSection().SetInfoTable('Duration',
                                               int(ulmapie.duration),
                                               str(ulmapie.duration))
        self._output.GetSection().SetInfoTable('Repetition Coding Indicator',
                                               int(ulmapie.repet_coding_ind),
                                               str(ulmapie.repet_coding_ind))           
        self._output.AddLine() 
    
    
    def OnReceiveULAllocStart(self,ulmapie) : 
        super(ULMAPDistillerHandler,self).OnReceiveULAllocStart(ulmapie)
        self._output.GetSection().SetSectionName('ULMAP IE UL Allocation Start')
        self._output.GetSection().SetInfoTable('OFDMA symbol offset',
                                               int(ulmapie.symbol_offset),
                                               str(ulmapie.symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel offset',
                                               int(ulmapie.subchannel_offset),
                                               str(ulmapie.subchannel_offset))
        self._output.GetSection().SetInfoTable('H-FDD UL subframe indicator',
                                               int(ulmapie.hfdd_ul_subframe_ind),
                                               str(ulmapie.hfdd_ul_subframe_ind))
        self._output.AddLine()
                    
    
    def OnReceiveCQICHEnhancedAlloc(self,ulmapie): 
        pass
    
    
    def OnReceiveHOAnchorActive(self,ulmapie): 
        pass
    
    
    def OnReceiveHOActiveAnchor(self,ulmapie): 
        pass
    
    
    def OnReceiveAnchorBSSwitch(self,ulmapie): 
        pass
    
    
    def OnReceiveULSoundingCommand(self,ulmapie): 
        pass
    
    
    def OnReceiveExt2UIUC(self,ulmapie): 
        pass
    
    
    def OnReceiveMIMOULEnhanced(self,ulmapie): 
        pass
    
    
    def OnReceiveHARQULMapIE(self,ulmapie): 
        pass
    
    
    def OnReceiveHARQACKCHRegionAlloc(self,ulmapie): 
        pass
    
    
    def OnReceiveMIMOULBasicIE(self,ulmapie): 
        pass
    
    
    def OnReceiveMiniSubchanAlloc(self,ulmapie): 
        pass
    
    
    def OnReceiveULPCBitmap(self,ulmapie): 
        pass
    
    
    def OnReceivePersistentHARQ(self,ulmapie): 
        pass
    
    
    def OnReceiveFDDPairedAlloc(self,ulmapie): 
        pass
    
    
    def OnReceiveAASSDMA(self,ulmapie): 
        pass
    
    
    def OnReceiveFeedbackPolling(self,ulmapie): 
        pass



class DLMAPDistillerHandler(DLMAPHandler):
    def __init__(self,output):
        super(DLMAPDistillerHandler,self).__init__()
        assert(isinstance(output,TextOutput))
        self._output = output
        
        
    def OnStartPDU(self,payload,macheader):
        super(DLMAPDistillerHandler,self).OnStartPDU(payload,macheader)
        self._output.BeginOutput()
        self._output.PrintPDUPayload(payload)
        self._output.AddLine()
        self._output.PrintPDUName('DLMAP')
        self._output.AddLine()
        self._output.PrintMACHeaderGeneric(macheader)
        self._output.AddLine()    
        
        
    def OnReceiveCRC(self,calc_crc,current_crc):
        self._output.PrintCRC(calc_crc,current_crc)
                
                
    def OnEndPDU(self):
        super(DLMAPDistillerHandler,self).OnEndPDU()
        self._output.AddLine()
        self._output.AddLine()                
        
        
    def OnReceiveDLMAP(self,dlmap):
        super(DLMAPDistillerHandler,self).OnReceiveDLMAP(dlmap)
        self._output.GetSection().SetSectionName('DLMAP')
        self._output.GetSection().SetInfoTable('Type', 2)
        self._output.GetSection().SetInfoTable('Frame Duration Code', dlmap.frame_duration_code)
        self._output.GetSection().SetInfoTable('Frame Number', dlmap.frame_number)
        self._output.GetSection().SetInfoTable('DCD Count', dlmap.dcd_count)
        self._output.GetSection().SetInfoTable('BSID', None,dlmap.bsid.strval)
        self._output.GetSection().SetInfoTable('Number OFDMA Symbols', 
                                               int(dlmap.num_ofdma_symbols),
                                               str(dlmap.num_ofdma_symbols))
        self._output.AddLine()
    
    
    def OnReceiveDLMAPIeBurstProfile(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveDLMAPIeBurstProfile(dlmapie)
        if len(dlmapie.cid_list) != 0 :
            self._output.GetSection().SetInfoTable('N_CID', int(len(dlmapie.cid_list)))
            subsection = self._output.GetSection().GetSection()
            for cid in dlmapie.cid_list:
                subsection.SetInfoTable('CID', int(cid))
            
        self._output.GetSection().SetSectionName('Burst Profile')
        self._output.GetSection().SetInfoTable('DIUC', int(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset', 
                                               int(dlmapie.ofdma_symbol_offset), 
                                               str(dlmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel Offset', 
                                               int(dlmapie.subchannel_offset), 
                                               str(dlmapie.subchannel_offset))
        self._output.GetSection().SetInfoTable('Boosting', 
                                               int(dlmapie.boosting), 
                                               str(dlmapie.boosting))
        self._output.GetSection().SetInfoTable('No OFDMA Symbols', 
                                               int(dlmapie.num_ofdma_symbols))
        self._output.GetSection().SetInfoTable('No Subchannels', int(dlmapie.num_subchannels))
        self._output.GetSection().SetInfoTable('Repetition Coding Indicator', int(dlmapie.repet_coding_ind),
                                               str(dlmapie.repet_coding_ind))
        self._output.AddLine()        

    
    def OnReceiveDLMAPIeCIDSwitch(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveDLMAPIeCIDSwitch(dlmapie)
        self._output.GetSection().SetSectionName('Information Element CID Switch')
        self._output.GetSection().SetInfoTable('DIUC', int(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC', int(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length', int(dlmapie.length))
        self._output.AddLine()

    
    def OnReceiveDLMAPIEChannelMeasurement(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveDLMAPIEChannelMeasurement(dlmapie)
        self._output.GetSection().SetSectionName('Information Element Channel Measurement') 
        self._output.GetSection().SetInfoTable('DIUC', 
                                               int(dlmapie.diuc),
                                               str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC', 
                                               int(dlmapie.ext_diuc),
                                               str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length', int(dlmapie.length))
        self._output.GetSection().SetInfoTable('Channel Nr', int(dlmapie.channel_nr))
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset', 
                                               int(dlmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('CID', int(dlmapie.cid))
        self._output.AddLine()        

        
    def OnReceiveSTC_Zone(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveSTC_Zone(dlmapie)
        self._output.GetSection().SetSectionName('DL STC Zone')
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC',int(dlmapie.ext_diuc),str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length',int(dlmapie.length),str(dlmapie.length))
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset',
                                               int(dlmapie.ofdma_symbol_offset),
                                               str(dlmapie.ofdma_symbol_offset))        
        self._output.GetSection().SetInfoTable('Permutation',
                                               int(dlmapie.permutation),
                                               str(dlmapie.permutation))        
        self._output.GetSection().SetInfoTable('Use All SC',
                                               int(dlmapie.use_all_sc),
                                               str(dlmapie.use_all_sc))        
        self._output.GetSection().SetInfoTable('STC',int(dlmapie.stc),str(dlmapie.stc))
        self._output.GetSection().SetInfoTable('Matrix Indicator',
                                               int(dlmapie.matrix_ind),
                                               str(dlmapie.matrix_ind))
        self._output.GetSection().SetInfoTable('DL_PermBase',
                                               int(dlmapie.dl_permbase),
                                               str(dlmapie.dl_permbase))        
        self._output.GetSection().SetInfoTable('PRBS_ID',
                                               int(dlmapie.prbs_id),
                                               str(dlmapie.prbs_id))
        self._output.GetSection().SetInfoTable('AMC Type',
                                               int(dlmapie.amc_type),
                                               str(dlmapie.amc_type))        
        self._output.GetSection().SetInfoTable('Midamble Presence',
                                               int(dlmapie.midamble_presence),
                                               str(dlmapie.midamble_presence))        
        self._output.GetSection().SetInfoTable('Midamble Boosting',
                                               int(dlmapie.midamble_boosting),
                                               str(dlmapie.midamble_boosting))                                
        self._output.GetSection().SetInfoTable('2/3 Antennas Select',
                                               int(dlmapie.antennas_2_3_select),
                                               str(dlmapie.antennas_2_3_select)) 
        self._output.GetSection().SetInfoTable('Dedicated Pilots',
                                               int(dlmapie.dedicated_pilots),
                                               str(dlmapie.dedicated_pilots))
        self._output.GetSection().SetInfoTable('Midamble Presence',int(dlmapie.reserved))
        self._output.AddLine()        


    def OnReceiveAASDL(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveAASDL(dlmapie)
        self._output.GetSection().SetSectionName('AAS DL')
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC',int(dlmapie.ext_diuc),str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length',int(dlmapie.length),str(dlmapie.length))
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset',int(dlmapie.ofdma_symbol_offset),
                                               str(dlmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Permutation',int(dlmapie.permutation),
                                               str(dlmapie.permutation))
        self._output.GetSection().SetInfoTable('DL Permutation Base',int(dlmapie.dl_permbase),
                                               str(dlmapie.dl_permbase))
        self._output.GetSection().SetInfoTable('DL Preamble Config',int(dlmapie.dl_preamble_config),
                                               str(dlmapie.dl_preamble_config))
        self._output.GetSection().SetInfoTable('Preamble Type',int(dlmapie.preamble_type),
                                               str(dlmapie.preamble_type))
        self._output.GetSection().SetInfoTable('PRBS ID',int(dlmapie.prbs_id),
                                               str(dlmapie.prbs_id))
        self._output.GetSection().SetInfoTable('Diversity MAP',int(dlmapie.diversity_map),
                                               str(dlmapie.diversity_map))
        self._output.GetSection().SetInfoTable('Reserved',int(dlmapie.reserved),str(dlmapie.reserved))
        self._output.AddLine()        
            
            
    def OnReceiveDataLocationAnotherBS(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveDataLocationAnotherBS(dlmapie)
        self._output.GetSection().SetSectionName('Data Location Another BS')
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC',int(dlmapie.ext_diuc),str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length',int(dlmapie.length),str(dlmapie.length))
        self._output.GetSection().SetInfoTable('Segment',int(dlmapie.segment),str(dlmapie.segment))
        self._output.GetSection().SetInfoTable('Used Subchannels',int(dlmapie.used_subchannels),str(dlmapie.used_subchannels))
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Frame Advance',int(dlmapie.frame_advance),str(dlmapie.frame_advance))
        self._output.GetSection().SetInfoTable('Reserved',int(dlmapie.reserved),str(dlmapie.reserved))
        self._output.GetSection().SetInfoTable('OFDMA Symbol Offset',int(dlmapie.ofdma_symbol_offset),str(dlmapie.ofdma_symbol_offset))
        self._output.GetSection().SetInfoTable('Subchannel Offset',int(dlmapie.subchannel_offset),str(dlmapie.subchannel_offset))
        self._output.GetSection().SetInfoTable('Boosting',int(dlmapie.boosting),str(dlmapie.boosting))
        self._output.GetSection().SetInfoTable('Preamble Index',int(dlmapie.preamble_index),str(dlmapie.preamble_index))
        self._output.GetSection().SetInfoTable('No. OFDM Symbols',int(dlmapie.no_ofdm_symbols),str(dlmapie.no_ofdm_symbols))
        self._output.GetSection().SetInfoTable('No. Subchannels',int(dlmapie.no_subchannels),str(dlmapie.no_subchannels))
        self._output.GetSection().SetInfoTable('Repetition Coding Indicator',int(dlmapie.repet_coding_ind),str(dlmapie.repet_coding_ind))
        self._output.GetSection().SetInfoTable('CID',int(dlmapie.cid),str(dlmapie.cid))  
        self._output.AddLine()                      
                                     

    def OnReceivePhysicalModifier(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceivePhysicalModifier(dlmapie)
        self._output.GetSection().SetSectionName('Physical Modifier')
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC',int(dlmapie.ext_diuc),str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length',int(dlmapie.length),str(dlmapie.length))
        self._output.GetSection().SetInfoTable('Preamble Modifier Type',
                                               int(dlmapie.preamble_modifier_type),
                                               str(dlmapie.preamble_modifier_type))
        if (int(dlmapie.preamble_modifier_type) == 0):
            self._output.GetSection().SetInfoTable('Preamble Frequency Shift Index',
                                                   int(dlmapie.preamble_frequency_shift_index),
                                                   str(dlmapie.preamble_frequency_shift_index))
        else:
            self._output.GetSection().SetInfoTable('Preamble Time Shift Index',
                                                   int(dlmapie.preamble_time_shift_index),
                                                   str(dlmapie.preamble_time_shift_index))
            
        self._output.GetSection().SetInfoTable('Pilot Pattern Modifier',
                                               int(dlmapie.pilot_pattern_modifier),
                                               str(dlmapie.pilot_pattern_modifier))
        self._output.GetSection().SetInfoTable('Pilot Pattern Index',
                                               int(dlmapie.pilot_pattern_index),
                                               str(dlmapie.pilot_pattern_index))            
        self._output.AddLine()                      


    def OnReceiveBroadcastCtrlPointer(self,dlmapie):
        super(DLMAPDistillerHandler,self).OnReceiveBroadcastCtrlPointer(dlmapie)
        self._output.GetSection.SetSectionName('Broadcast Control Pointer')
        self._output.GetSection().SetInfoTable('DIUC',int(dlmapie.diuc),str(dlmapie.diuc))
        self._output.GetSection().SetInfoTable('Extended DIUC',int(dlmapie.ext_diuc),str(dlmapie.ext_diuc))
        self._output.GetSection().SetInfoTable('Length',int(dlmapie.length),str(dlmapie.length))
        self._output.GetSection().SetInfoTable('DCD UCD Trans Frame',
                                               int(dlmapie.dcd_ucd_trans_frame),
                                               str(dlmapie.dcd_ucd_trans_frame))
        self._output.GetSection().SetInfoTable('Skip Broadcast System Update',
                                               int(dlmapie.skip_sys_broadcast_sys_update),
                                               str(dlmapie.skip_sys_broadcast_sys_update))
        if(int(dlmapie.skip_sys_broadcast_sys_update)==0):
            self._output.GetSection().SetInfoTable('Broadcast System Update Type',
                                                   int(dlmapie.broadcast_sys_update_type),
                                                   str(dlmapie.broadcast_sys_update_type))
        else:
            self._output.GetSection().SetInfoTable('Broadcast System Update Transmission Frame',
                                                   int(dlmapie.broadcast_sys_update_trans_frame),
                                                   str(dlmapie.broadcast_sys_update_trans_frame))        
            
        self._output.AddLine()                                      
        


class DCDDistillerHandler(DCDHandler):
    def __init__(self,output):
        super(DCDDistillerHandler,self).__init__()
        assert(isinstance(output,TextOutput))
        self._output = output
        
    def OnStartPDU(self,payload,macheader):
        super(DCDDistillerHandler,self).OnStartPDU(payload,macheader)
        self._output.BeginOutput()
        self._output.PrintPDUPayload(payload)
        self._output.AddLine()        
        self._output.PrintPDUName('Downlink Channel Descriptor')
        self._output.AddLine()                
        self._output.PrintMACHeaderGeneric(macheader)
        self._output.AddLine()


    def OnReceiveCRC(self,calc_crc,current_crc):
        self._output.PrintCRC(calc_crc,current_crc)
        
    
    def OnEndPDU(self):
        super(DCDDistillerHandler,self).OnEndPDU()
        self._output.AddLine()
        
            
    def OnReceiveDCD(self,dcd):
        super(DCDDistillerHandler,self).OnReceiveDCD(dcd)
        self._output.GetSection().SetSectionName('DCD')
        self._output.GetSection().SetInfoTable('Type', 1)
        self._output.GetSection().SetInfoTable('Reserved', int(dcd.reserved))
        self._output.GetSection().SetInfoTable('Configuration Change Count', int(dcd.conf_change_count))
        self._output.AddLine()
        self._output.GetSection().SetSectionName('DCD Channel Encodings')

    
    def OnReceiveBurstProfile(self,burstprofile):
        super(DCDDistillerHandler,self).OnReceiveBurstProfile(burstprofile)
        self._output.GetSection().SetInfoTable('Type', int(burstprofile.type),'Burst Profile')
        self._output.GetSection().SetInfoTable('Length', int(burstprofile.length))
        self._output.GetSection().SetInfoTable('Reserved', int(burstprofile.reserved))
        self._output.GetSection().SetInfoTable('DIUC', int(burstprofile.diuc))
        subsection = self._output.GetSection().GetSection()
        for tlv in burstprofile.tlv_list:
            subsection.SetInfoTable('Type', int(tlv.Type),str(tlv.Type))
            subsection.SetInfoTable('Length', int(tlv.Length))
            subsection.SetInfoTable('Value', int(tlv.Value))
        self._output.AddLine()                       

    
    def OnReceiveChannelEncoding(self,tlv):
        super(DCDDistillerHandler,self).OnReceiveChannelEncoding(tlv)
        self._output.GetSection().SetInfoTable('Type', int(tlv.Type), str(tlv.Type))
        self._output.GetSection().SetInfoTable('Length', int(tlv.Length))
        if(tlv.Length > 4):
            self._output.GetSection().SetInfoTable('Value',None,DumpBuffString(tlv.Value.GetValueAsString(),tlv.Length))
        else:
            self._output.GetSection().SetInfoTable('Value',int(tlv.Value))        
        self._output.AddLine()



class MACDataDistillerHandler(DataHandler):
    def __init__(self,output):
        super(MACDataDistillerHandler,self).__init__()
        self._output = output
            
    def OnStartPDU(self,payload,macheader):
        super(MACDataDistillerHandler,self).OnStartPDU(payload,macheader)
        self._output.BeginOutput()
        self._output.PrintPDUPayload(payload)
        self._output.AddLine()        
        self._output.PrintPDUName('MAC Data PDU')
        self._output.AddLine()                
        self._output.PrintMACHeaderGeneric(macheader)
        self._output.AddLine()
    
    
    def OnReceiveCRC(self,calc_crc,current_crc):
        self._output.PrintCRC(calc_crc,current_crc)    
    
    
    def OnEndPDU(self):
        super(MACDataDistillerHandler,self).OnEndPDU()
        self._output.AddLine()
        self._output.AddLine()                


    def OnError(self,errstring):
        pass


        
def main():
    try:
        config = ArgvParser().Parse(sys.argv[1:])
        if config == None:
            return
        
        if config.output == '':
            config.output = 'ofdmadistiller.log'
            
        if config.output_format == DistillerConfig.OUTPUT_FORMAT_ENUM.HTML:
            raise NotImplementedError,'not implemented output format'
        if(config.inputformat == DistillerConfig.INPUT_FORMAT_ENUM.C_ARRAY_1BYTE):
            inputfile = CArrayFormat(config.inputfile,CArrayFormat.BYTE_SIZE)
        elif(config.inputformat == DistillerConfig.INPUT_FORMAT_ENUM.C_ARRAY_2BYTE):
            inputfile = CArrayFormat(config.inputfile,CArrayFormat.SHORT_SIZE)
        elif(config.inputformat == DistillerConfig.INPUT_FORMAT_ENUM.C_ARRAY_4BYTE):
            inputfile = CArrayFormat(config.inputfile,CArrayFormat.WORD_SIZE)            
        
        if(config.output == ''):
            textoutput = TextOutput('ofdmadistiller.log')
        else:
            textoutput = TextOutput(config.output)      
            
        #set output verbosity
        textoutput.Verbosity = config.verbose                  

        handlercollection = MMHandlerCollection()
        handlercollection.ucdhandler    = UCDDistillerHandler(textoutput)
        handlercollection.ulmaphandler  = ULMAPDistillerHandler(textoutput)
        handlercollection.dlmaphandler  = DLMAPDistillerHandler(textoutput)
        handlercollection.dcdhandler    = DCDDistillerHandler(textoutput)
        handlercollection.datahandler   = MACDataDistillerHandler(textoutput)
        decoder = PDUDecoder(handlercollection)
        inputvector = inputfile.ReadNextPayload()
        while(inputvector):
            try:
                decoder.Decode(inputvector)            
            except PDUMMError , err:
                textoutput.BeginOutput()
                textoutput.PrintPDUPayload(inputvector)
                textoutput.AddLine()
                textoutput.PrintMACHeaderGeneric(err.macheader)
                textoutput.AddLine()
                textoutput.WriteLine('ERROR: %s \n' % str(err))            
                textoutput.AddLine()
                textoutput.AddLine()
            finally:
                inputvector = inputfile.ReadNextPayload()
        
                
    except NotImplementedError, err:
        print err


if __name__ == '__main__':
    main()